#pragma once

#include <string>

enum WaveForm
{
	Sine = 0,
	Triangular,
	Square,
	Sawtooth,
	Random,
	UserFunc1,
	UserFunc2,
	UserFunc3
};

class Sample
{
public:
	Sample(void);
	Sample(int length);
	Sample(short* data, int length);
	~Sample(void);

	short* data;
	int length;

	Sample* Copy(double intensity, int maxVariation);
	Sample* Append(Sample* sample);
	Sample* LowPassFilter(float gain, float neg, float pos);
	Sample* LowPass400Filter();
	Sample* LowPass6000Filter();
	void AddWhiteNoise(double intensity);
	void AddBrownNoise(double intensity);
};

class WaveSample : public Sample
{
public:
	WaveSample(void);
	WaveSample(std::string& name, short* sample, int length, int rate, double frequency);
	~WaveSample(void);

	std::string name;
	int rate;
	double frequency;

	static void WaveLoop(WaveSample* sample, int phaseCount, void(*WaveLoopCb)(WaveSample*,int,int,int));
	static WaveSample* CreateSample(std::string& name, double frequency, int rate, void(*WaveSampleCb)(WaveSample*));
	static WaveSample* TriangularSample(std::string& name, double frequency, int rate);
	static WaveSample* SineSample(std::string& name, double frequency, int rate);
	static WaveSample* RandomSample(std::string& name, double frequency, int rate);
	static WaveSample* SquareSample(std::string& name, double frequency, int rate);
	static WaveSample* SawtoothSample(std::string& name, double frequency, int rate);

};

enum Slope
{
	Full = 0,
	Up,
	Down,
	Bell,
	RBell
};

struct WaveComponent
{
	int waveIndex;
	int phaseIndex;
	WaveForm waveForm;
	double frequencyStart;
	double frequencyEnd;
	Slope frequencyShape;
	double intensity;
	int intensityVariation;
	Slope intensityShape;		
	WaveSample* sample;
};
